package reflect_test;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

//反射测试
public class Test {                           /*这里需要抛出异常*/
    public static void main(String[] args) throws Exception{
//        //1.获取Student类的class对象  /*这里需要强制类型转换*/       /*包名 + 类名*/
//        Class<Student> cla1 = (Class<Student>) Class.forName("reflect_test.Student");
//        //2.通过类名称.class获取class对象
//        Class<Student> clas2 = Student.class;
//        //3.通过Student对象的getClass方法
//                               /*这里需要强制类型转换*/
//        Class<Student> clas3 = (Class<Student>) new Student().getClass();
//        System.out.println(cla1 == clas2);//比较地址
//        System.out.println(cla1 == clas3);//比较地址


//        Person per = new Student();
//        System.out.println(per.getClass());

        //2.通过类名称.class获取class对象
        Class<Student> clas2 = Student.class;
//        //获取所有public权限的构造方法
//        Constructor[] constructors = clas2.getConstructors();
//        for(Constructor constructor : constructors){
//            System.out.println(constructor);
//        }
//        System.out.println("----------------------------");
//        //获取该类所有的构造方法
//        Constructor[] constructors1 = clas2.getDeclaredConstructors();
//        for(Constructor constructor : constructors1){
//            System.out.println(constructor);
//        }

        //获取指定类型的有参构造
//        Constructor<Student> constructor = clas2.getDeclaredConstructor(String.class, String.class, int.class);
//        System.out.println(constructor);
//         //通过反射直接调用的方法
//        Student student = constructor.newInstance("张三", "男", 18);
//        System.out.println(student);

//        Constructor<Student> constructor = clas2.getDeclaredConstructor(String.class);
//        //破坏封装，通过反射破坏private封装，调用私有构造方法
//        constructor.setAccessible(true);
//        Student student = constructor.newInstance("张三");
//        System.out.println(student);

        // 2.获取要调用方法的Method对象
//        Method method1 = clas2.getDeclaredMethod("test");
//        // test是静态方法，无需产生Student对象
//        method1.invoke(null);
//        System.out.println("------------------------");
//        Method method2 = clas2.getDeclaredMethod("fun",String.class);
//        //不是静态方法，所有需要产生一个对象。
//        Student student = new Student("李四","男",28);//这步就是普通的产生对象调用构造方法
//        method2.invoke(student,"我好想打酱油啊~~~");

        // 3.获取要拿到的属性Field对象
        Field field = clas2.getDeclaredField("country");
        System.out.println(field.get(null));//若为静态对象，传入null
        Field field1 = clas2.getDeclaredField("age");
        Student student = new Student("李四","男",28);
        System.out.println(field1.get(student));
        field1.set(student,20);
        System.out.println(field1.get(student));
    }
}
